#pragma once
#include "reactor/noncopyable.hpp"
#include "reactor/tcp_connection.hpp"
#include <map>
#include <string>
#include <memory>
#include <functional>

namespace reactor {
class EventLoop;
class Acceptor;
class EventLoopThreadPool;

/**
 * @brief 高层封装的 TCP 服务器
 */
class TcpServer : noncopyable {
public:
    using TcpConnectionPtr = std::shared_ptr<TcpConnection>;
    using ConnectionCallback = std::function<void(const TcpConnectionPtr&)>;
    using MessageCallback = std::function<void(const TcpConnectionPtr&, Buffer*)>;

    TcpServer(EventLoop* loop, const std::string& ip, uint16_t port);
    ~TcpServer();

    void start();
    void setThreadNum(int numThreads);

    void setConnectionCallback(const ConnectionCallback& cb) { _connectionCallback = cb; }
    void setMessageCallback(const MessageCallback& cb) { _messageCallback = cb; }

    // 提供给 SearchServer 使用的方法，通过 connfd 发送消息
    void sendMessage(int connfd, const std::string& data);

    std::string ip() const;
    uint16_t port() const;

private:
    void newConnection(int sockfd, const struct sockaddr_in& peerAddr);
    void removeConnection(const TcpConnectionPtr& conn);
    void removeConnectionInLoop(const TcpConnectionPtr& conn);

    using ConnectionMap = std::map<int, TcpConnectionPtr>;

    EventLoop* _loop; // main aacptor loop
    std::string _ip;
    uint16_t _port;
    std::unique_ptr<Acceptor> _acceptor;
    std::shared_ptr<EventLoopThreadPool> _threadPool;

    ConnectionCallback _connectionCallback;
    MessageCallback _messageCallback;

    bool _started;
    int _nextConnId;
    ConnectionMap _connections;
};
} // namespace reactor
